"""
    使用dearpygui控制双摄像头多线程系统窗口展示,保存正侧两张图像分析
"""
import dearpygui.dearpygui as dpg
# import camera
import camera as camera
import face
import numpy as np
import time
import cv2
import datetime
from adProAna import read_item

import os

from print_dayin import create_word

from decimal import ROUND_HALF_UP, Decimal

import yaml

from print_by_pdf import test

import threading

from three_image_proc import proc_img_ad

f = open(r'config.yaml', encoding="utf-8")
y = yaml.load(f, Loader=yaml.FullLoader)
video_path = y["video_path"]

def to_decimal(num, exp="0.0000", rounding=ROUND_HALF_UP) -> Decimal:
    """
       转 Decimal，四舍五入
       :param num: int,str,float,Decimal
       :param exp: 精度
       :param rounding: 圆整模式
       :return: Decimal
       """
    if not num:
        return Decimal("0").quantize(exp=Decimal(exp), rounding=rounding)
    if not isinstance(num, str):
        num = str(num)
    return Decimal(num).quantize(exp=Decimal(exp), rounding=rounding)

# 摄像头1的线程函数
class CamThread1(threading.Thread):
    def __init__(self, para="hi", sleep=3):
        super().__init__()
        self.para = para
        self.sleep = sleep
        self.camera_width = None
        self.camera_height = None
        self.fourCC = None
        self.raw_data = None

    def xxx(self):
        # 获取cap，视频高度，视频宽度
        # _, _, camera_height, camera_width = camera.camera()
        _, _, camera_height, camera_width = camera.camera1()
        self.raw_data = np.zeros((camera_height, camera_width, 3), np.float32)

        # 创建纹理
        with dpg.texture_registry(show=False):
            texture_id = dpg.add_raw_texture(camera_width, camera_height, self.raw_data, format=dpg.mvFormat_Float_rgb)
        # 创建Raw Video窗口
        with dpg.window(label="Camera", width=camera_width, height=camera_height, pos=(0, 40), no_resize=True,
                        no_title_bar=True, no_move=True, no_background=True, no_scrollbar=True):
            dpg.add_image(texture_id)

        start_time = time.time()

        # 播放视频每一帧
        with dpg.window(label="Keybord", width=1280, height=300, pos=(0, 750), no_resize=True, no_title_bar=True,
                        no_move=True,
                        no_background=True, no_scrollbar=True):
            # 保存视频文件流初始化设置
            global flag, filename, out
            flag = False
            self.fourCC = cv2.VideoWriter_fourcc(*'X264')

            dpg.add_text(label="show result screen", tag="text item", color=(0, 255, 0))
            dpg.add_input_text(label="请输入姓名", width=480, tag="name")
            dpg.add_input_text(label="请输入性别", width=480, tag="sex")
            # dpg.add_checkbox(label="性别：男", tag="sex")
            # dpg.add_checkbox(label="性别：女", tag="sex")
            dpg.add_input_text(label="请输入年龄", width=480, tag="age")
            dpg.add_button(label="开始", callback=self.record_flag)
            dpg.add_button(label="结束", callback=self.analysis_flag)
            dpg.add_button(label="打印", callback=self.print_out)

    def record_flag(self):
        global flag, filename, out, name, sex, age  # 使用外部变量需要定义全局声明
        # _, _, camera_height, camera_width = camera.camera()
        _, _, camera_height, camera_width = camera.camera1()
        # _, _, camera_height, camera_width = camera.camera2()
        name = dpg.get_value("name")
        times = datetime.datetime.now(tz=None)
        timestamp = str(times.hour).rjust(2, "0") + str(times.minute).rjust(2, "0") + str(times.second).rjust(2,
                                                                                                              "0")
        filename = name + "  " + timestamp + ".mp4"
        sex = dpg.get_value("sex")
        age = dpg.get_value("age")
        # out = cv2.VideoWriter(filename, fourCC, 5, (640, 480))
        out = cv2.VideoWriter("jack.mp4", self.fourCC, 5, (camera_width, camera_height))
        print("准备获取人脸图像...")
        dpg.set_value("text item", "准备获取人脸图像...")
        if flag == False:
            flag = True

    def analysis_flag(self):
        global filename, out, flag, info, pro  # 使用外部变量需要定义全局声明
        # global zheng_image, ce_image, feature1, feature2, feature3, feature4, feature5
        global image_list, feature_list
        # _, _, camera_height, camera_width = camera.camera()
        img1, _, camera_height, camera_width = camera.camera1()
        img2, _, camera_height, camera_width = camera.camera2()

        print("开始腺样体分析...")
        dpg.set_value("text item", "开始腺样体分析...")

        feature_figs, feature_prob = proc_img_ad(img1, img2, img2)

        if flag:
            flag = False
        out.release()

        # os.rename("jack.mp4", "F:/projects/data/video/" + filename)
        os.rename("jack.mp4", video_path + filename)

        # 腺样体概率分析
        # zheng_image, ce_image, pro = read_item(video_path + filename)
        # feature1, feature2, feature3, feature4, feature5 = face.show_keypoint_pairs_five(zheng_image, camera_width,
        #                                                                                  camera_height,
        #                                                                                  face.faceMesh)
        # cv2.imwrite(video_path + "zheng.jpg", zheng_image)
        # cv2.imwrite(video_path + "ce.jpg", ce_image)
        # cv2.imwrite(video_path + "feature1.jpg", feature1)
        # cv2.imwrite(video_path + "feature2.jpg", feature2)
        # cv2.imwrite(video_path + "feature3.jpg", feature3)
        # cv2.imwrite(video_path + "feature4.jpg", feature4)
        # cv2.imwrite(video_path + "feature5.jpg", feature5)
        # image_list = [video_path + "zheng.jpg", video_path + "ce.jpg"]
        # feature_list = [video_path + "feature1.jpg", video_path + "feature2.jpg", video_path + "feature3.jpg",
        #                 video_path + "feature4.jpg", video_path + "feature5.jpg"]
        dpg.set_value("text item",
                      "腺样体肥大患病风险：" + str(round(to_decimal(feature_prob["predict_xianyangti"]) * 100, 2)) + "%")
        # info = "腺样体肥大患病风险：" + str(round(pro["predict_xianyangti"], 3)*100) + "%"
        info = "腺样体肥大患病风险：" + str(round(to_decimal(feature_prob["predict_xianyangti"]) * 100, 2)) + "%"

    def print_out(self):
        # 结果写入文档并打印
        global filename, info, name, sex, age, pro, image_list, feature_list
        # create_word(filename, info)
        test(name, sex, age, image_list, feature_list, \
             [(str(round(to_decimal(pro["results"]["眼内眦间距与鼻翼宽度"]), 2)), 0.11),
              (str(round(to_decimal(pro["results"]["口唇至下颌下缘与整个面部长度"]), 2)), 0.33),
              (str(round(to_decimal(pro["results"]["上唇上缘至鼻小柱距离与下唇上缘至鼻小柱距离"]), 2)), 0.10),
              (str(round(to_decimal(pro["results"]["下唇下面积与脸部全面积"]), 2)), 0.10),
              (str(round(to_decimal(pro["results"]["唇上下间距与鼻小柱至下颌下缘间距"]), 2)), 0.10),
              (str(round(to_decimal(pro["results"]["颧骨平面横距与口裂平面横距"]), 2)), 0.10),
              (str(round(to_decimal(pro["results"]["鼻梁高度与鼻尖高度"]), 2)), 0.08),
              (str(round(to_decimal(pro["results"]["下颌角至口角与下颌角至下颌前缘"]), 2)), 0.04),
              (str(round(to_decimal(pro["results"]["外耳道口至颧骨前缘与外耳道口至下颌骨前缘"]), 2)), 0.04)],
             str(round(to_decimal(pro["predict_xianyangti"]) * 100, 2)) + "%")

    def run(self):
        window_camera1(self)
        # window_camera_gui()

        # time.sleep(self.sleep)
        # print(self.para)


# 摄像头2的线程函数
class CamThread2(threading.Thread):
    def __init__(self, para="hi", sleep=3):
        super().__init__()
        self.para = para
        self.sleep = sleep
        self.camera_width = None
        self.camera_height = None
        self.fourCC = None
        self.raw_data = None

    def xxx(self):
        # 获取cap，视频高度，视频宽度
        # _, _, camera_height, camera_width = camera.camera()
        _, _, camera_height, camera_width = camera.camera2()
        self.raw_data = np.zeros((camera_height, camera_width, 3), np.float32)

        # 创建纹理
        with dpg.texture_registry(show=False):
            texture_id = dpg.add_raw_texture(camera_width, camera_height, self.raw_data, format=dpg.mvFormat_Float_rgb)
        # 创建Raw Video窗口
        with dpg.window(label="Camera", width=camera_width, height=camera_height, pos=(640, 40), no_resize=True,
                        no_title_bar=True, no_move=True, no_background=True, no_scrollbar=True):
            dpg.add_image(texture_id)

        # 播放视频每一帧
        # with dpg.window(label="Keybord", width=1280, height=300, pos=(0, 750), no_resize=True, no_title_bar=True,
        #                 no_move=True,
        #                 no_background=True, no_scrollbar=True):
        #     # 保存视频文件流初始化设置
        #     global flag, filename, out
        #     flag = False
        #     self.fourCC = cv2.VideoWriter_fourcc(*'X264')
        #
        #     dpg.add_text(label="show result screen", tag="text item", color=(0, 255, 0))
        #     dpg.add_input_text(label="请输入姓名", width=480, tag="name")
        #     dpg.add_input_text(label="请输入性别", width=480, tag="sex")
        #     # dpg.add_checkbox(label="性别：男", tag="sex")
        #     # dpg.add_checkbox(label="性别：女", tag="sex")
        #     dpg.add_input_text(label="请输入年龄", width=480, tag="age")
        #     dpg.add_button(label="开始", callback=self.record_flag)
        #     dpg.add_button(label="结束", callback=self.analysis_flag)
        #     dpg.add_button(label="打印", callback=self.print_out)

    def record_flag(self):
        global flag, filename, out, name, sex, age  # 使用外部变量需要定义全局声明
        _, _, camera_height, camera_width = camera.camera()
        # _, _, camera_height, camera_width = camera.camera1()
        # _, _, camera_height, camera_width = camera.camera2()
        name = dpg.get_value("name")
        times = datetime.datetime.now(tz=None)
        timestamp = str(times.hour).rjust(2, "0") + str(times.minute).rjust(2, "0") + str(times.second).rjust(2,
                                                                                                              "0")
        filename = name + "  " + timestamp + ".mp4"
        sex = dpg.get_value("sex")
        age = dpg.get_value("age")
        # out = cv2.VideoWriter(filename, fourCC, 5, (640, 480))
        out = cv2.VideoWriter("jack.mp4", self.fourCC, 5, (camera_width, camera_height))
        print("开始录制视频...")
        dpg.set_value("text item", "开始录制视频...")
        if flag == False:
            flag = True

    def analysis_flag(self):
        global filename, out, flag, info, pro  # 使用外部变量需要定义全局声明
        # global zheng_image, ce_image, feature1, feature2, feature3, feature4, feature5
        global image_list, feature_list
        _, _, camera_height, camera_width = camera.camera()
        print("开始腺样体分析...")
        dpg.set_value("text item", "开始腺样体分析...")
        if flag:
            flag = False
        out.release()

        # os.rename("jack.mp4", "F:/projects/data/video/" + filename)
        os.rename("jack.mp4", video_path + filename)

        # 腺样体概率分析
        zheng_image, ce_image, pro = read_item(video_path + filename)
        # feature = face.show_keypoint_pairs(zheng_image, iw, ih, face.faceMesh)
        feature1, feature2, feature3, feature4, feature5 = face.show_keypoint_pairs_five(zheng_image, camera_width,
                                                                                         camera_height,
                                                                                         face.faceMesh)
        cv2.imwrite(video_path + "zheng.jpg", zheng_image)
        cv2.imwrite(video_path + "ce.jpg", ce_image)
        cv2.imwrite(video_path + "feature1.jpg", feature1)
        cv2.imwrite(video_path + "feature2.jpg", feature2)
        cv2.imwrite(video_path + "feature3.jpg", feature3)
        cv2.imwrite(video_path + "feature4.jpg", feature4)
        cv2.imwrite(video_path + "feature5.jpg", feature5)
        image_list = [video_path + "zheng.jpg", video_path + "ce.jpg"]
        feature_list = [video_path + "feature1.jpg", video_path + "feature2.jpg", video_path + "feature3.jpg",
                        video_path + "feature4.jpg", video_path + "feature5.jpg"]
        dpg.set_value("text item",
                      "腺样体肥大患病风险：" + str(round(to_decimal(pro["predict_xianyangti"]) * 100, 2)) + "%")
        # info = "腺样体肥大患病风险：" + str(round(pro["predict_xianyangti"], 3)*100) + "%"
        info = "腺样体肥大患病风险：" + str(round(to_decimal(pro["predict_xianyangti"]) * 100, 2)) + "%"

    def print_out(self):
        # 结果写入文档并打印
        global filename, info, name, sex, age, pro, image_list, feature_list
        global zheng_image, ce_image, feature1, feature2, feature3, feature4, feature5
        # create_word(filename, info)
        test(name, sex, age, image_list, feature_list, \
             [(str(round(to_decimal(pro["results"]["眼内眦间距与鼻翼宽度"]), 2)), 0.11),
              (str(round(to_decimal(pro["results"]["口唇至下颌下缘与整个面部长度"]), 2)), 0.33),
              (str(round(to_decimal(pro["results"]["上唇上缘至鼻小柱距离与下唇上缘至鼻小柱距离"]), 2)), 0.10),
              (str(round(to_decimal(pro["results"]["下唇下面积与脸部全面积"]), 2)), 0.10),
              (str(round(to_decimal(pro["results"]["唇上下间距与鼻小柱至下颌下缘间距"]), 2)), 0.10),
              (str(round(to_decimal(pro["results"]["颧骨平面横距与口裂平面横距"]), 2)), 0.10),
              (str(round(to_decimal(pro["results"]["鼻梁高度与鼻尖高度"]), 2)), 0.08),
              (str(round(to_decimal(pro["results"]["下颌角至口角与下颌角至下颌前缘"]), 2)), 0.04),
              (str(round(to_decimal(pro["results"]["外耳道口至颧骨前缘与外耳道口至下颌骨前缘"]), 2)), 0.04)],
             str(round(to_decimal(pro["predict_xianyangti"]) * 100, 2)) + "%")

    def run(self):
        window_camera2(self)
        # window_camera_gui()

        # time.sleep(self.sleep)
        # print(self.para)


def window_main():
    # 创建dpg应用
    dpg.create_context()
    # 创建应用窗口
    dpg.create_viewport(title="Adenoid Hypertrophy Risk Predict System - Developed by Laibo AI",
                        small_icon="logo1.ico", large_icon='logo1.ico', width=1920, height=1080, x_pos=0, y_pos=0)
    dpg.setup_dearpygui()

    # 注册字体，自选字体
    with dpg.font_registry():
        with dpg.font("SIMSUN.TTC", 28) as font_simsun:  # 增加中文编码范围（中文字体常规宋体），防止问号
            dpg.add_font_range_hint(dpg.mvFontRangeHint_Default)
            dpg.add_font_range_hint(dpg.mvFontRangeHint_Chinese_Simplified_Common)
            dpg.add_font_range_hint(dpg.mvFontRangeHint_Chinese_Full)
        dpg.bind_font(font_simsun)

    # 显示应用界面
    dpg.show_viewport()

    '''
        start:插入各个窗口
    '''
    thread_cam1 = CamThread1()
    thread_cam1.xxx()
    thread_cam2 = CamThread2()
    thread_cam2.xxx()
    thread_cam1.start()
    thread_cam2.start()

    dpg.start_dearpygui()

    '''
        end:插入各个窗口
    '''
    # 销毁dpg
    dpg.destroy_context()


def window_title():
    with dpg.window(label="Title", width=1920, height=35, pos=(0, 0), no_resize=True, no_title_bar=True, no_move=True,
                    no_background=True, no_scrollbar=True):
        dpg.draw_text(text="莱博AI腺样体肥大风险预测系统", pos=(200, 0), color=(255, 255, 255), size=35)

def window_camera1(ob):

    while dpg.is_dearpygui_running():
        # print('xxxxxx')
        # img_raw, img_rgb, camera_height, camera_width = camera.camera()
        img_raw, img_rgb, camera_height, camera_width = camera.camera1()
        imgProcessed = face.show_keypoint_pairs(img_rgb, camera_width, camera_height, face.faceMesh)

        if flag:
            # print("xxxxx")
            # print("img_raw:", img_raw)
            out.write(img_raw)

        imgNorm = camera.normalize(imgProcessed)
        ob.raw_data[...] = imgNorm[...]

        # dpg.render_dearpygui_frame()

def window_camera2(ob):

    while dpg.is_dearpygui_running():
        # print('xxxxxx')
        # img_raw, img_rgb, camera_height, camera_width = camera.camera()
        img_raw, img_rgb, camera_height, camera_width = camera.camera2()
        imgProcessed = face.show_keypoint_pairs(img_rgb, camera_width, camera_height, face.faceMesh)

        if flag:
            # print("xxxxx")
            # print("img_raw:", img_raw)
            out.write(img_raw)

        imgNorm = camera.normalize(imgProcessed)
        ob.raw_data[...] = imgNorm[...]

        # dpg.render_dearpygui_frame()

if __name__ == '__main__':
    # 创建两个线程分别打开摄像头
    # t1 = threading.Thread(target=camera1_thread)
    c1 = CamThread1()
    # t2 = threading.Thread(target=camera2_thread)
    c2 = CamThread2()
    # 启动线程
    c1.start()
    c2.start()
    # 等待线程结束
    c1.join()
    c2.join()